package examples.jsf.lifecycle.impl;

import examples.jsf.FacesException;
import examples.jsf.lifecycle.Lifecycle;
import examples.jsf.context.FacesContext;
import examples.jsf.event.PhaseEvent;
import examples.jsf.event.PhaseId;
import examples.jsf.event.PhaseListener;

import java.util.ListIterator;

/**
 * @author Bill
 * @version 2013-05-29
 */
public abstract class Phase {

    public void doPhase(FacesContext context, Lifecycle lifecycle, ListIterator<PhaseListener> phaseListeners) {

        PhaseEvent event = null;

        if (phaseListeners.hasNext()) {
            event = new PhaseEvent(context, this.getId(), lifecycle);
        }

        try{
            handleBeforePhase(context, phaseListeners, event);

            execute(context);
        }
        catch (FacesException e) {
            // handle exception
        }
        finally {
            handleAfterPhase(context, phaseListeners, event);
        }
    }

    public abstract void execute(FacesContext context) throws FacesException;

    public abstract PhaseId getId();

    protected void handleAfterPhase(FacesContext context, ListIterator<PhaseListener> phaseListeners, PhaseEvent event) {}

    protected void handleBeforePhase(FacesContext context, ListIterator<PhaseListener> phaseListeners, PhaseEvent event) {}

}
